package cn.source.zk.service.impl;

import cn.source.common.utils.NumberUtils;
import cn.source.common.utils.SecurityUtils;
import cn.source.zk.domain.entity.ConnectionPoint;
import cn.source.zk.domain.entity.Substation;
import cn.source.zk.mapper.ZkConnectionPointMapper;
import cn.source.zk.mapper.ZkSubstationMapper;
import cn.source.zk.service.IZkAreaService;
import cn.source.zk.service.IZkConnectionPointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class ZkConnectionServiceImpl implements IZkConnectionPointService {

    @Autowired
    private ZkConnectionPointMapper connectionPointMapper;

    @Autowired
    private ZkSubstationMapper substationMapper;

    @Autowired
    private IZkAreaService areaService;

    /**
     * 查询并网点分页列表
     *
     * @param connectionPoint
     * @return
     */
    public List<ConnectionPoint> listPage(ConnectionPoint connectionPoint) {

        connectionPoint.setAreaChildNums(areaService.getChild(connectionPoint.getArea()));

        //查询当前用户有权限看到的变电站
        Substation substation = new Substation();
        //设置当前用户
        substation.setCompanyId(SecurityUtils.getCompanyId());
        List<Substation> substationsList = substationMapper.selectListPage(substation);
        List<Long> substationsNumList = substationsList.stream().map(Substation::getNum).collect(Collectors.toList());
        //查询并网点
        return connectionPointMapper.selectListPage(connectionPoint,substationsNumList);

    }

    /**
     * 新增并网点
     *
     * @param connectionPoint
     * @return
     */
    @Transactional
    public int add(ConnectionPoint connectionPoint) {

        //更新变电站的的的容量和并网点数量
        ArrayList<ConnectionPoint> connectionPoints = new ArrayList<>();
        connectionPoints.add(connectionPoint);
        updateSubStationCapacityAndPointsAmount(connectionPoints, "set");

        //查询祖级列表
        connectionPoint.setAncestorNames(areaService.getAncestorName(connectionPoint.getArea()));

        return connectionPointMapper.addConnectionPoint(connectionPoint);
    }


    /**
     * 根据num查询connectionPoint
     *
     * @param num
     * @return
     */
    public ConnectionPoint getByNum(Long num) {
        //return connectionPointMapper.selectListPage(connectionPoint,null).get(0);
        return connectionPointMapper.getByNum(num);
    }

    /**
     * 修改并网点
     *
     * @param connectionPoint
     * @return
     */
    @Transactional
    public int edit(ConnectionPoint connectionPoint) {

        List<Long> nums = new ArrayList<>();
        nums.add(connectionPoint.getNum());
        //根据num查询出没有修改前的并网点容量和所属变电站
        List<ConnectionPoint> oldConnectionPoint = connectionPointMapper.getByNums(nums);
        //更新变电站的的的容量和并网点数量
        updateSubStationCapacityAndPointsAmount(oldConnectionPoint, "reset");

        //更新变电站的的的容量和并网点数量
        ArrayList<ConnectionPoint> connectionPoints = new ArrayList<>();
        connectionPoints.add(connectionPoint);
        updateSubStationCapacityAndPointsAmount(connectionPoints, "set");


        //查询祖级列表
        connectionPoint.setAncestorNames(areaService.getAncestorName(connectionPoint.getArea()));

        return connectionPointMapper.edit(connectionPoint);
    }

    /**
     * 批量删除并网点
     *
     * @param nums
     * @return
     */
    public int deleteBatch(List<Long> nums) {
        List<ConnectionPoint> connectionPoints = connectionPointMapper.getByNums(nums);

        //更新变电站的的的容量和并网点数量
        updateSubStationCapacityAndPointsAmount(connectionPoints, "reset");

        return connectionPointMapper.deleteBatch(nums);
    }

    /**
     * 校验并网点名称在当前变电站下是否存在
     *
     * @param name
     * @return
     */
    public boolean checkConnectionPointExist(String name, Long substation, Long num) {

        ConnectionPoint connectionPoint = new ConnectionPoint();
        connectionPoint.setConnectionPointName(name);
        connectionPoint.setSubstationNum(substation);
        connectionPoint.setNum(num);

        int result = connectionPointMapper.checkConnectionPointExist(connectionPoint);
        return result > 0;
    }

    @Override
    public List<ConnectionPoint> getBySubstationNums(Iterable<Long> nums) {

        return connectionPointMapper.getBySubstationNums(nums);
    }

    /**
     * @param connectionPoints
     * @param method           值set(设置新数据,相当于新增)或者reset(重置变电站数据重置到上一次修改并网点之前,然后新增新的并网点,相当于修改)
     */
    private void updateSubStationCapacityAndPointsAmount(List<ConnectionPoint> connectionPoints, String method) {
        //更新变电站的的的容量和并网点数量
        List<Substation> substations = new ArrayList<>();
        Substation substation = new Substation();

        for (ConnectionPoint connectionPoint : connectionPoints) {


            substation.setNum(connectionPoint.getSubstationNum());
            List<Substation> list = substationMapper.selectListPage(substation);
            Double totalCapacity = 0.0;
            Integer pointsAmount = 0;
            if (Objects.equals(method, "set")) {
                totalCapacity =
                        (list.get(0).getTotalCapacity() == null ? 0 : list.get(0).getTotalCapacity()) + connectionPoint.getCapacity();
                pointsAmount =
                        (list.get(0).getPointsAmount() == null ? 0 : list.get(0).getPointsAmount()) + 1;
            } else if (Objects.equals(method, "reset")) {
                totalCapacity =
                        (list.get(0).getTotalCapacity() == null ? 0 : list.get(0).getTotalCapacity()) - connectionPoint.getCapacity();
                pointsAmount =
                        (list.get(0).getPointsAmount() == null ? 0 : list.get(0).getPointsAmount()) - 1;
            }

            substation.setTotalCapacity(NumberUtils.random3(totalCapacity));
            substation.setPointsAmount(pointsAmount);

            substations.add(substation);
        }


        substationMapper.updateBatch(substations);
    }
}
